package net.protocol.diameter;

import net.protocol.diameter.dictionary.AVPFormatFactory;
import net.protocol.diameter.dictionary.DiameterFormatFactory;
import net.protocol.diameter.dictionary.MessageFormatFactory;
import net.protocol.diameter.message.AbstractDiameterMessage;
import net.protocol.diameter.message.DiameterMessage;

import java.nio.ByteBuffer;

/**
 * This class parses a Diameter Message from given source ByteBuffer.
 * 
 * @author jinhongw@gmail.com
 */
public class DiameterParser {
    private final AVPFormatFactory avpFormatFactory;
    private final MessageFormatFactory messageFormatFactory;

    /**
     * @param avpFormatKey
     *          DiameterFormatFactory's register key for <tt>AvpFormatFactory</tt>
     * @param messageFormatKey
     *          DiameterFormatFactory's register key for <tt>MessageFormatFactory</tt>
     */
    public DiameterParser(String avpFormatKey,
                          String messageFormatKey) {
        this(DiameterFormatFactory.getAvpFormatFactory(avpFormatKey),
                DiameterFormatFactory.getMessageFormatFactory(messageFormatKey));
    }

    /**
     * @param avpFormatFactory
     *          A specified implementation of the <tt>AvpFormatFactory</tt> interface
     * @param messageFormatFactory
     *          A specified implementation of the <tt>MessageFormatFactory</tt> interface
     */
    public DiameterParser(AVPFormatFactory avpFormatFactory,
                    MessageFormatFactory messageFormatFactory) {
        if (avpFormatFactory == null)
            throw new IllegalArgumentException("AVPFormatFactory is null");
        this.avpFormatFactory = avpFormatFactory;

        if (messageFormatFactory == null)
            throw new IllegalArgumentException("MessageFormatFactory is null");
        this.messageFormatFactory = messageFormatFactory;
    }

	/**
	 * Creates a new <code>DiameterMessage</code> with the given
	 * <code>MessageFormat</code> and <code>ByteBuffer</code>
     *
	 * @param src
	 *            The buffer from which bytes are to be retrieved
	 * @return a new <code>DiameterMessage</code>
	 */
	public DiameterMessage parse(ByteBuffer src) {
		return new AbstractDiameterMessage(messageFormatFactory, src);
	}

    public AVPFormatFactory getAVPFormatFactory() {
        return this.avpFormatFactory;
    }

    public MessageFormatFactory getMessageFormatFactory() {
        return this.messageFormatFactory;
    }
}
